tree grammar ConstructionsCounter;

options 
{
	tokenVocab=LPMEDLexer; // use the vocabulary from the parser
	ASTLabelType=CommonTree; // what kind of trees are we walking?
	language = CSharp2;
	output = AST;
}

@namespace { Core.ANTLRGrammars }

@header
{
using System.Collections.Generic;
}
@members
{
	public List<string> Constructions = new List<string>();
}

program :
	^(CPROGRAM ^(CDEVICE name=ID) block)
;


block : 
	(varDecList)* blockStmt
;


varDecList : 
	varDecListAtom+ 
;


varDecListAtom :
	^(CTYPE TYPE peremDecList)
;


peremDecList : ID+;


blockStmt : ^(CSTATEMENT stmt*)
;


stmt
options { backtrack=true;}
:			assign
		|	ifStmt {Constructions.Add("ifStmt");}
		|	^(CWHILE expr blockStmt) {Constructions.Add("while");}
		|	^(CFOR assign expr assign blockStmt) {Constructions.Add("for");}
		|	deviceFuncID
		|	blockStmt {Constructions.Add("blockStmt");}
		|	^(CBREAKPOINT INT) {Constructions.Add("breakpoint");}
		|	CTERMINATEALL {Constructions.Add("terminateall");}
		|	functionCall
;

assign options{backtrack=true;}	
:	
	^(CASSIGN ID expr {Constructions.Add("assign");})
;

ifStmt
options { backtrack=true; }
: 
	^(CIFTE expr blockStmt blockStmt?)
;

expr options{backtrack=true;}
:	
			^(OpOr expr expr )
		|	^(OpAnd expr expr )
		|	^(OpLogicalB expr expr )
		|	^(OpLogicalA expr expr )
		|	^(OpAddSub expr expr )
		|	^(OpDivMul expr expr )
		|	^(OpNegation expr )
		|	^(OpUnar expr )
		|	'(' expr ')'
		|	atom
;

atom
options
{
	backtrack=true;
}	
 :
   ID
 | ^(CFLOAT FLOAT)
 | ^(CINT INT)
 | ^(CBOOL DBOOL)
 | ^(OBJECTNAME ID) ^(NODES ID*) ^(MEMBERNAME ID)
 | ^(CGETSTATE ^(OBJECTNAME ID) ^(NODES ID*))
;

qualifiedName	:
	^(OBJECTNAME ID) ^(NODES ID*) ^(MEMBERNAME ID)
;

deviceFuncID 	
:       
        ^(CCALL ^(CSYNCCALL qualifiedName)) {Constructions.Add("syncCall");}
	|	^(CCALL ^(CASYNCCALL qualifiedName)) {Constructions.Add("asyncCall");}
	|	^(CCALL ^(CENDTHECALL qualifiedName)) {Constructions.Add("endTheCall");}
	|	^(CCALL ^(CWAITTHECALL qualifiedName)) {Constructions.Add("waitTheCall");}
	|	^(CCALL ^(CWAITANYCALL qualifiedName)) {Constructions.Add("waitAnyCall");}
;


functionCall
: 
			^(CASYNCFUNCCALL ID parameter*) {Constructions.Add("asyncFuncCall");}
		| 	^(CWAITFUNCFINISH ID parameter*) {Constructions.Add("waitFuncFinish");}
		|	^(CSYNCFUNCCALL ID parameter*) {Constructions.Add("syncFuncCall");}
;


parameter	: 
	^(PARAM parameterValue)
;

parameterValue	:
			ID		//variable
		| 	INT		//number
		|	qualifiedName	//named state
;